package com.hzy.elastic.service.impl;

import com.hzy.elastic.entity.QSchool;
import com.hzy.elastic.entity.QStudent;
import com.hzy.elastic.entity.Student;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 *     通过上面构造的 jpaQuery
 *     jpaQuery.fetchResults(); 查询list ，返回 list 泛型根据是否有多表查询，
 *     如果没有就返回 比如上面的QBlogInfo 对应的 BlogInfo ==》 list<BlogInfo>，
 *     如果有多表查询 返回 list<tuple> 类型，再根据tuple.get(0) tuple.get(1) 去获取对应的属性
 *     jpqQuery.fetchOne();  查询单条记录 比如where id = xxx 的时候可以使用
 */
@Service
public class JpaService {
    @Resource
    private JPAQueryFactory queryFactory;

    public void selectStudent(){
        QStudent qStudent = QStudent.student;
        List<Student> students = queryFactory.selectFrom(qStudent).fetch();
        System.out.println(students);
    }

    public void selectStudentWithWhere() {
        QStudent qStudent = QStudent.student;
        //单表单条件查询
        List<Student> students = queryFactory.selectFrom(qStudent).where(qStudent.age.goe(2)).fetch();
        //单表多条件and查询
        List<Student> studentList = queryFactory.selectFrom(qStudent).where(qStudent.age.goe(2).and(qStudent.name.eq("vincent"))).fetch();
        //单表多条件or查询
        List<Student> list = queryFactory.selectFrom(qStudent).where(qStudent.age.goe(20).or(qStudent.name.eq("vincent"))).fetch();
        //单表排序分页查询
        List<Student> list1 = queryFactory.selectFrom(qStudent).offset(1).limit(3).orderBy(qStudent.id.desc()).fetch();
        System.out.println(students);
        System.out.println(studentList);
        System.out.println(list);
        System.out.println(list1);
    }

    public void selectOne(Long id){
        QStudent qStudent = QStudent.student;
        QSchool qSchool = QSchool.school;
        List<Student> students = queryFactory.selectFrom(qStudent).fetch();
        System.out.println(students);

        Tuple tuple = queryFactory.select(qStudent, qStudent.age)
                .from(qStudent)
                .leftJoin(qSchool)
                .on(qStudent.schoolId.eq(qSchool.id))
                .where(qStudent.id.eq(id))
                .fetchOne();
        QStudent result = tuple.get(0, QStudent.class);
        System.out.println(result);
    }

    public void selectStudent1() {
        QStudent qStudent = QStudent.student;
        QSchool qSchool = QSchool.school;
        List<Student> students = queryFactory.select(qStudent).from(qSchool, qStudent).where(qSchool.id.eq(qStudent.schoolId)).fetch();
        System.out.println(students);
    }

    public void selectStudent2() {
        QStudent qStudent = QStudent.student;
        QSchool qSchool = QSchool.school;
        List<Tuple> students = queryFactory.select(qStudent.age, qStudent.name, qSchool.name).from(qSchool, qStudent).where(qSchool.id.eq(qStudent.schoolId)).fetch();
        List<Map<String, Object>> maps = students.stream().map(tuple -> {
            Map<String, Object> map = new HashMap<>();
            map.put("studentName", tuple.get(qStudent.name));
            map.put("age", tuple.get(qStudent.age));
            map.put("schoolName", tuple.get(qSchool.name));
            return map;
        }).collect(Collectors.toList());
        System.out.println(maps);
    }

    public void selectStudent3() {
        QStudent qStudent = QStudent.student;
        QSchool qSchool = QSchool.school;
        List<Student> students = queryFactory.select(qStudent)
                .from(qStudent)
                .leftJoin(qSchool)
                .on(qStudent.schoolId.eq(qSchool.id))
                .fetch();
        System.out.println(students);
    }

    @Transactional
    public void testUpdate() {
        QStudent qStudent = QStudent.student;
        Long result = queryFactory.update(qStudent)
                .set(qStudent.name, "haha")
                .where(qStudent.id.eq(111L)).execute();
    }

    @Transactional
    public void testDelete() {
        QStudent qStudent = QStudent.student;
        //删除指定的一个
        Long result = queryFactory.delete(qStudent)
                .where(qStudent.id.eq(111L))
                .execute();
        //删除所有
        Long totalResult = queryFactory.delete(qStudent)
                .execute();
        System.out.println(totalResult);
    }
}